package org.proteored.miapeapi.xml.ms.adapter;

import java.util.List;
import java.util.Set;

import org.proteored.miapeapi.cv.ControlVocabularyManager;
import org.proteored.miapeapi.interfaces.Adapter;
import org.proteored.miapeapi.interfaces.DateAdapter;
import org.proteored.miapeapi.interfaces.MiapeDate;
import org.proteored.miapeapi.interfaces.ms.Acquisition;
import org.proteored.miapeapi.interfaces.ms.DataAnalysis;
import org.proteored.miapeapi.interfaces.ms.InstrumentConfiguration;
import org.proteored.miapeapi.interfaces.ms.MSAdditionalInformation;
import org.proteored.miapeapi.interfaces.ms.MSContact;
import org.proteored.miapeapi.interfaces.ms.MiapeMSDocument;
import org.proteored.miapeapi.interfaces.ms.ResultingData;
import org.proteored.miapeapi.interfaces.ms.Spectrometer;
import org.proteored.miapeapi.xml.ms.autogenerated.MIAPESoftwareType;
import org.proteored.miapeapi.xml.ms.autogenerated.MSAcquisition;
import org.proteored.miapeapi.xml.ms.autogenerated.MSDataAnalysis;
import org.proteored.miapeapi.xml.ms.autogenerated.MSInstrumentConfiguration;
import org.proteored.miapeapi.xml.ms.autogenerated.MSMIAPEMS;
import org.proteored.miapeapi.xml.ms.autogenerated.MSResultingData;
import org.proteored.miapeapi.xml.ms.autogenerated.MSSpectrometer;
import org.proteored.miapeapi.xml.ms.autogenerated.ObjectFactory;
import org.proteored.miapeapi.xml.ms.autogenerated.ParamType;
import org.proteored.miapeapi.xml.ms.util.MsControlVocabularyXmlFactory;

/**
 * Implementation of {@link MSMIAPEMS} from a {@link MiapeMSDocument} object.
 * 
 * @author Salva
 * 
 */
public class MiapeMsXMLAdapter implements Adapter<MSMIAPEMS> {
	private final ObjectFactory factory;
	private final MiapeMSDocument document;
	private final MsControlVocabularyXmlFactory cvFactory;
	private static org.apache.log4j.Logger log = org.apache.log4j.Logger
			.getLogger("log4j.logger.org.proteored");

	public MiapeMsXMLAdapter(MiapeMSDocument document,
			ControlVocabularyManager cvManager) {
		log.info("MiapeMsXMLAdapter");
		this.factory = new ObjectFactory();
		this.document = document;
		this.cvFactory = new MsControlVocabularyXmlFactory(factory, cvManager);
	}

	@Override
	public MSMIAPEMS adapt() {
		log.info("Adding MIAPE Data");
		MSMIAPEMS xmlMiape = factory.createMSMIAPEMS();
		log.info("Adding MIAPE Data");
		addMiapeData(xmlMiape);
		log.info("adding instrumentConfigurations");
		List<InstrumentConfiguration> instrumentConfigurations = document
				.getInstrumentConfigurations();
		if (instrumentConfigurations != null)
			addInstrumentConfigurations(xmlMiape.getMSInstrumentConfiguration(),
					instrumentConfigurations);

		Set<Acquisition> acquisitions = document.getAcquisitions();
		if (acquisitions != null)
			addAcquisitions(xmlMiape.getMSAcquisition(), acquisitions);

		Set<DataAnalysis> dataAnalysis = document.getDataAnalysis();
		if (dataAnalysis != null)
			addDataAnalysis(xmlMiape.getMSDataAnalysis(), dataAnalysis);
		/*
		 * Set<Quantitation> quantitations = document.getQuantitations(); if
		 * (quantitations != null)
		 * addQuantitations(xmlMiape.getMSQuantitation(), quantitations);
		 */
		List<ResultingData> resultingDatas = document.getResultingDatas();
		if (resultingDatas != null)
			addResultingDatas(xmlMiape.getMSResultingData(), resultingDatas);
		Set<Spectrometer> spectrometers = document.getSpectrometers();
		if (spectrometers != null)
			addSpectrometer(xmlMiape.getMSSpectrometer(), spectrometers);

		List<MSAdditionalInformation> additionalInformations = document.getAdditionalInformations();
		if (additionalInformations != null)
			addAdditionalInformations(xmlMiape.getMSAdditionalInformation(), additionalInformations);

		return xmlMiape;
	}

	private void addInstrumentConfigurations(
			List<MSInstrumentConfiguration> xmlInstrumentConfiguration,
			List<InstrumentConfiguration> instrumentConfigurations) {
		if (instrumentConfigurations == null)
			return;
		for (InstrumentConfiguration instrumentConfiguration : instrumentConfigurations) {
			xmlInstrumentConfiguration.add(new InstrumentConfigurationAdapter(
					instrumentConfiguration, factory, cvFactory).adapt());
		}

	}

	private void addSpectrometer(List<MSSpectrometer> xmlSpectrometers,
			Set<Spectrometer> spectrometers) {
		if (spectrometers == null)
			return;
		for (Spectrometer spectrometer : spectrometers) {
			xmlSpectrometers.add(new SpectrometerAdapter(spectrometer, factory, cvFactory).adapt());
		}

	}

	private void addAdditionalInformations(List<ParamType> xmlAddInfos,
			List<MSAdditionalInformation> addInfos) {
		if (addInfos == null)
			return;
		for (MSAdditionalInformation addInfo : addInfos) {
			xmlAddInfos.add(new AdditionalInformationAdapter(addInfo, factory, cvFactory).adapt());
		}
	}

	private void addResultingDatas(List<MSResultingData> xmlResultingDatas,
			List<ResultingData> resultingDatas) {
		if (resultingDatas == null)
			return;
		for (ResultingData resultingData : resultingDatas) {
			MSResultingData xmlResultingData = new ResultingDataAdapter(resultingData, factory,
					cvFactory).adapt();
			/*
			 * addSpectrumDescription(xmlResultingData.getMSSpectrumDescription()
			 * , resultingData.getSpectrumDescriptions());
			 */
			xmlResultingDatas.add(xmlResultingData);
		}
	}

	/*
	 * private void addSpectrumDescription(List<MSSpectrumDescription>
	 * xmlSpectrumDescription, List<SpectrumDescription> spectrumDescriptions) {
	 * if (spectrumDescriptions == null) return; for (SpectrumDescription
	 * spectrumDescription : spectrumDescriptions) {
	 * xmlSpectrumDescription.add(new
	 * SpectrumDescriptionAdapter(spectrumDescription, factory,
	 * cvFactory).adapt()); } }
	 */

	/*
	 * private void addQuantitations(List<MSQuantitation> xmlQuantitations,
	 * Set<Quantitation> quantitations) { if (quantitations == null) return; for
	 * (Quantitation quantitation : quantitations) { MSQuantitation
	 * xmlQuantitation = new QuantitationAdapter(quantitation, factory).adapt();
	 * addSoftwares(xmlQuantitation.getMSQuantitationSoftware(),
	 * quantitation.getQuantitationSoftwares());
	 * xmlQuantitations.add(xmlQuantitation); } }
	 */

	private void addDataAnalysis(List<MSDataAnalysis> xmlDataAnalysises,
			Set<DataAnalysis> dataAnalysises) {
		if (dataAnalysises == null)
			return;
		for (DataAnalysis dataAnalysis : dataAnalysises) {
			MSDataAnalysis xmlDataAnalysis = new DataAnalysisAdapter(dataAnalysis, factory,
					cvFactory).adapt();

			MIAPESoftwareType miapeSoftware = new SoftwareAdapter(dataAnalysis, factory, cvFactory)
					.adapt();

			xmlDataAnalysis.setParametersLocation(dataAnalysis.getParametersLocation());
			xmlDataAnalysis.setCatalogNumber(miapeSoftware.getCatalogNumber());
			xmlDataAnalysis.setVersion(miapeSoftware.getVersion());
			xmlDataAnalysis.setURI(miapeSoftware.getURI());
			xmlDataAnalysis.setComments(miapeSoftware.getComments());
			xmlDataAnalysis.setCustomizations(miapeSoftware.getCustomizations());
			xmlDataAnalysis.setDescription(miapeSoftware.getDescription());
			xmlDataAnalysis.setManufacturer(miapeSoftware.getManufacturer());
			xmlDataAnalysis.setModel(miapeSoftware.getModel());
			xmlDataAnalysis.setName(miapeSoftware.getName());
			xmlDataAnalysis.setParameters(miapeSoftware.getParameters());
			xmlDataAnalysises.add(xmlDataAnalysis);
		}

	}

	private void addAcquisitions(List<MSAcquisition> xmlAcquisitions, Set<Acquisition> acquisitions) {
		if (acquisitions == null)
			return;
		for (Acquisition acquisition : acquisitions) {
			MSAcquisition acquisitionXML = new AcquisitionAdapter(acquisition, factory, cvFactory)
					.adapt();

			// analysisSoftwareXML.setMSControlAnalysisSoftwareDetails(new
			// SoftwareAdapter(controlAnalysisSoftware, factory,
			// cvFactory).adapt());
			MIAPESoftwareType miapeSoftware = new SoftwareAdapter(acquisition, factory, cvFactory)
					.adapt();
			acquisitionXML.setCatalogNumber(miapeSoftware.getCatalogNumber());
			acquisitionXML.setVersion(miapeSoftware.getVersion());
			acquisitionXML.setURI(miapeSoftware.getURI());
			acquisitionXML.setComments(miapeSoftware.getComments());
			acquisitionXML.setCustomizations(miapeSoftware.getCustomizations());
			acquisitionXML.setDescription(miapeSoftware.getDescription());
			acquisitionXML.setManufacturer(miapeSoftware.getManufacturer());
			acquisitionXML.setModel(miapeSoftware.getModel());
			acquisitionXML.setName(miapeSoftware.getName());
			acquisitionXML.setParameters(miapeSoftware.getParameters());

			xmlAcquisitions.add(acquisitionXML);
		}
	}

	private void addMiapeData(MSMIAPEMS xmlMiape) {
		log.info("Adding ID");

		int id = document.getId();
		if (id > 0) {
			xmlMiape.setId(id);
		} else {
			xmlMiape.setId(-1);
		}

		log.info("Adding date");
		log.info("document");
		log.info("document" + document.getClass());

		MiapeDate date = document.getDate();
		log.info("date" + date);
		if (date != null && date.getValue() != null) {
			xmlMiape.setDate(date.getValue());
		}

		// if (document.getModificationDate() != null) {
		// xmlMiape.setModificationDate(document.getModificationDate().);
		// }
		log.info("Adding contact");

		MSContact contact = document.getContact();
		if (contact != null)
			xmlMiape.setMSContact(new ContactAdapter(contact, factory, cvFactory).adapt());
		log.info("Adding name");

		xmlMiape.setName(document.getName());
		log.info("Pride Url");

		xmlMiape.setAttachedFileLocation(document.getAttachedFileLocation());

		if (document.getTemplate() != null) {
			xmlMiape.setTemplate(document.getTemplate());
		} else {
			xmlMiape.setTemplate(Boolean.FALSE);
		}

		xmlMiape.setVersion(document.getVersion());
		log.info("Project");

		if (document.getProject() != null)
			xmlMiape.setMIAPEProject(new ProjectAdapter(document.getProject(), factory).adapt());

		log.info("Adding Modif Date");

		if (document.getModificationDate() != null) {
			xmlMiape.setModificationDate(new DateAdapter(document.getModificationDate()).adapt());
		}
		log.info("End all MiapeData");
	}

}
